﻿using System;
using System.Collections.Generic;
using System.Net;
using System.Web.Services.Protocols;
using MSPE.Public.FOSS.AutoStatusPlus.TimerJob;

namespace MSPE.Public.FOSS.AutoStatusPlus.Common
{
    public class WebServiceManager
    {
        #region Public Properties
        public ICredentials Credentials { get; set; }
        public string PwaUrl { get; set; }
        public string SspUrl { get; set; }
        #endregion // Public Properties

        #region Private / Protected
        private readonly Dictionary<WebServiceTypeEnum, SoapHttpClientProtocol> _webRefs;
        private readonly Dictionary<WebServiceTypeEnum, string> _webRefPaths;        
        #endregion // Private / Protected

        #region Constructors
        public WebServiceManager()
        {
            // Init web refs
            _webRefs = new Dictionary<WebServiceTypeEnum, SoapHttpClientProtocol>();
            _webRefPaths = new Dictionary<WebServiceTypeEnum, string>();

            // Init web ref paths
            _webRefPaths.Add(WebServiceTypeEnum.Events, "/_vti_bin/PSI/Events.asmx");
            _webRefPaths.Add(WebServiceTypeEnum.Resource, "/_vti_bin/PSI/Resource.asmx");
            _webRefPaths.Add(WebServiceTypeEnum.Statusing, "/_vti_bin/PSI/Statusing.asmx");
            _webRefPaths.Add(WebServiceTypeEnum.StatusingDerived, "/PSI/Statusing.asmx");
            _webRefPaths.Add(WebServiceTypeEnum.TimeSheet, "/_vti_bin/PSI/Timesheet.asmx");

        } // WebServiceManager()
        #endregion // Constructors

        #region Methods
        public void Clear()
        {
            foreach (SoapHttpClientProtocol _webRef in _webRefs.Values)
                _webRef.Dispose();

            _webRefs.Clear();
        } // Clear()

        private void CreateWebRef(WebServiceTypeEnum webServiceType)
        {
            if (Enum.IsDefined(typeof(WebServiceTypeEnum), webServiceType))
            {
                switch (webServiceType)
                {
                    case (WebServiceTypeEnum.Events):
                        // Create, add, and init web ref
                        _webRefs.Add(webServiceType, new EventsSvc.Events());
                        break;
                    case (WebServiceTypeEnum.Resource):
                        // Create, add, and init web ref
                        _webRefs.Add(webServiceType, new ResourceSvc.Resource());
                        break;
                    case (WebServiceTypeEnum.Statusing):
                        // Create, add, and init web ref
                        _webRefs.Add(webServiceType, new StatusingSvc.Statusing());
                        break;
                    case (WebServiceTypeEnum.StatusingDerived):
                        // Create, add, and init web ref
                        _webRefs.Add(webServiceType, new StatusingDerived());
                        break;
                    case (WebServiceTypeEnum.TimeSheet):
                        // Create, add, and init web ref
                        _webRefs.Add(webServiceType, new TimesheetSvc.TimeSheet());
                        break;
                    default:
                        throw new ArgumentOutOfRangeException("webServiceType", "Web Service of type " + webServiceType + " is not supported.");
                } // switch

                InitWebRef(webServiceType);
                return;
            } // End if

            throw new ArgumentOutOfRangeException("webServiceType", "Web Service of type " + webServiceType + " is not supported.");
        } // CreateWebRef()

        private void InitWebRef(WebServiceTypeEnum webServiceType)
        {
            // If no PWA URL is defined, throw exception
            if (String.IsNullOrEmpty(PwaUrl))
                throw new Exception("PwaUrl not set.");

            // If no credentials are defined, use DefaultCredentials
            if (Credentials == null) Credentials = CredentialCache.DefaultCredentials;

            // Use the SSP URL for Derived classes
            if (webServiceType.ToString().Contains("Derived"))
            {
                // If no SSP URL is defined, throw exception
                if (String.IsNullOrEmpty(SspUrl))
                    throw new Exception("SspUrl not set.");

                // Set up web ref
                _webRefs[webServiceType].Credentials = Credentials;
                _webRefs[webServiceType].Url = SspUrl + _webRefPaths[webServiceType];
                return;
            }

            // Set up web ref
            _webRefs[webServiceType].Credentials = Credentials;
            _webRefs[webServiceType].Url = PwaUrl + _webRefPaths[webServiceType];
        } // InitWebService()
        
        public SoapHttpClientProtocol GetWebRef(WebServiceTypeEnum webServiceType)
        {
            if (!_webRefs.ContainsKey(webServiceType))
                CreateWebRef(webServiceType);

            return _webRefs[webServiceType];
        } // GetWebService()
        #endregion // Methods
    }
}